package com.woniuxy.lab.woniu_lab.controller;


import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.woniuxy.lab.woniu_lab.commons.Result;
import com.woniuxy.lab.woniu_lab.model.Exper;
import com.woniuxy.lab.woniu_lab.model.User;
import com.woniuxy.lab.woniu_lab.service.ExperService;
import com.woniuxy.lab.woniu_lab.service.UserService;
import com.woniuxy.lab.woniu_lab.service.dto.ExperDto;
import com.woniuxy.lab.woniu_lab.service.dto.experDto.MyExperDto;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;

/**
 * <p>
 * 实验表 前端控制器
 * </p>
 *
 * @author Silas
 * @since 2023-03-15
 */
@RestController
@RequestMapping("/exper")
@Api(tags = "[D]实验环境相关接口")
@Slf4j
@Validated
public class ExperController {

    @Resource
    private ExperService experService;

    @Resource
    private UserService userService;


    /**
     * ps：如果是文件类实验，先提醒他是否关闭进行中实验
     * 查询用户是否存在正在运行的环境，没有会返回null，存在返回ExperDto
     * @return ExperDto
     */
    @ApiOperation("47 判断用户运行中的实验")
    @GetMapping("/runningOrNot")
    public Result<ExperDto> runningOrNot(){
        log.info("开始查询用户是否存在正在运行的环境");
        ExperDto experDto= experService.runningOrNot();
        if (ObjectUtil.isEmpty(experDto))
            return Result.success(200,"查询用户是否存在正在运行的环境成功",null);
        return Result.success(200,"查询用户是否存在正在运行的环境成功",experDto);
    }

    /**
     * 环境延时
     * @param rangeId 靶场ID
     * @return ExperDto 实验详情
     */
    @ApiOperation("50 实验环境延时")
    @PutMapping("/delay")
    public Result<ExperDto> delay(@ApiParam(value = "靶场ID") @RequestParam
                                      @NotNull(message = "靶场ID不能为空") @Min(value = 1,message = "靶场ID最小为1") Integer rangeId){
        User user = userService.assertUser();
        log.info("实验环境延时,用户id:{}",user.getId());
        experService.delay(user,rangeId);
        return Result.success(200,"延时30分钟成功",null);
    }

    /**
     * 提交Flag
     * @return Boolean 是否通过验证 通过为true 未通过为false
     */
    @ApiOperation("51 提交并验证flag")
    @GetMapping("/checkFlag")
    public Result<Boolean> checkFlag(@ApiParam(value = "flag")
                                         @NotBlank(message = "flag不能为空") String flag,
                                     @ApiParam(value = "rangeId") @NotNull(message = "靶场ID不能为空")
                                     @Min(value = 1,message = "靶场ID最小为1") Integer rangeId) {
        log.info("开始验证flag：{},rangeId:{}", flag,rangeId);
        Boolean b = experService.checkFlag(flag,rangeId);
        return Result.success(200, "提交Flag成功", b);
    }

    @ApiOperation("22 查询我的CTF实验记录")
    @GetMapping("/getMyCTF")
    public Result<IPage<MyExperDto>> getMyCTF(
            @ApiParam(value = "第几页") @Min(value = 1,message = "当前页最小为1") @NotNull(message = "当前页不能为空") Integer page,
            @ApiParam(value = "每页条数") @NotNull(message = "展示数量不能为空") @Max(value = 50,message = "展示数量最大为50")
            @Min(value = 1,message = "展示数量最小为1") Integer size){
        log.info("查询登录用户进行过的CTF实验页码{}大小{}",page,size);
        IPage<Exper> iPage = new Page<>(page == null ? 1 : page, size == null ? 10 : size);
        IPage<MyExperDto> myExperDtoIPage = experService.getMyCTF(iPage);
        return Result.success(200,"查询成功",myExperDtoIPage);
    }

    @ApiOperation("19 查询我的安全实验记录")
    @GetMapping("/getMyExper")
    public Result<IPage<MyExperDto>> getMyExper(
            @ApiParam(value = "第几页") @Min(value = 1,message = "当前页最小为1") @NotNull(message = "当前页不能为空") Integer page,
            @ApiParam(value = "每页条数") @NotNull(message = "展示数量不能为空") @Max(value = 50,message = "展示数量最大为50")
            @Min(value = 1,message = "展示数量最小为1") Integer size
    ){
        log.info("查询我的安全实验记录页码{}大小{}",page,size);
        IPage<Exper> iPage = new Page<>(page == null ? 1 : page, size == null ? 10 : size);
        IPage<MyExperDto> myExperDtoIPage = experService.getMyExper(iPage);

        return Result.success(200,"查询成功",myExperDtoIPage);
    }
}

